package com.appspot.aliga.openligadb;

import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl;

import java.util.logging.Logger;

import com.appspot.aliga.League;
import com.appspot.aliga.openligadb.service.ArrayOfMatchResult;
import com.appspot.aliga.openligadb.service.ArrayOfMatchdata;
import com.appspot.aliga.openligadb.service.Group;
import com.appspot.aliga.openligadb.service.MatchResult;
import com.appspot.aliga.openligadb.service.Matchdata;
import com.appspot.aliga.openligadb.service.Sportsdata;
import com.appspot.aliga.openligadb.service.SportsdataSoap;
import com.appspot.aliga.persistence.Gameday;
import com.appspot.aliga.persistence.Match;
import com.appspot.aliga.persistence.PersistenceService;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.googlecode.objectify.NotFoundException;

public class OpenLigaDBUpdater {

    private static final Logger log = Logger.getLogger(OpenLigaDBUpdater.class.getName());

    public void updateAllMatches() {
        PersistenceService ps = new PersistenceService();
        SportsdataSoap service = new Sportsdata().getSportsdataSoap();

        League[] leagues = League.values();
        for (League league : leagues) {

            for (int gameday = 1; gameday <= league.getGameDays(); gameday++) {

                // check if gameday is Complete
                Gameday gd = ps.getGameday(league.getId(), gameday);
                if (gd != null && gd.isComplete()) {
                    // gameday is complete --> continue
                    continue;
                } else if (gd == null) {
                    gd = new Gameday();
                    gd.setDay(gameday);
                    gd.setLeagueID(league.getId());
                    gd.setComplete(false);
                }

                ArrayOfMatchdata machdata = service
                        .getMatchdataByGroupLeagueSaison(gameday,
                                league.getOldbShortcut(), league.getSeason());
                for (Matchdata matchdata : machdata.getMatchdata()) {
                    saveMacthData(ps, league, matchdata);
                }

                Group group = service.getCurrentGroup(league.getOldbShortcut());

                // is gamedayComplete
                if (gameday < group.getGroupOrderID()) {
                    gd.setComplete(true);
                } else {
                    gd.setComplete(false);
                }

                // save Gameday
                ps.saveGameday(gd);
            }
        }
    }

    public void updateCurrentGameDay() {
        League[] leagues = League.values();
        for (League league : leagues) {
            Queue queue = QueueFactory.getDefaultQueue();
            queue.add(withUrl("/worker").param("leagueID", league.getId() + "").method(Method.GET));
            log.fine("add league " + league + " to queue.");
        }
    }

    public void updateLeague(PersistenceService ps, LeagueTableUpdater ltu,
                             SportsdataSoap service, League league) {
        int currentGameday = service.getCurrentGroupOrderID(league.getOldbShortcut());
        ArrayOfMatchdata machdata = service.getMatchdataByGroupLeagueSaison(currentGameday, league.getOldbShortcut(), league.getSeason());
        boolean changedResults = false;
        for (Matchdata matchdata : machdata.getMatchdata()) {
            boolean change = saveMacthData(ps, league, matchdata);
            if (change && changedResults == false) {
                changedResults = true;
            }
        }

        if (changedResults) {
            log.info("the results for league " + league + " changed. -> updating table");
            ltu.updateForLeague(league);
        }

    }

    private boolean saveMacthData(PersistenceService ps, League league,
                                  Matchdata matchdata) {
        int matchID = matchdata.getMatchID();
        Match match = null;
        try {
            match = ps.findMatch(matchID);
        } catch (NotFoundException e) {
            match = new Match();
            match.setMatchID(new Long(matchID));
            match.setGameDay(matchdata.getGroupOrderID());
            match.setLeagueID(league.getId());
            match.setMatchDate(matchdata.getMatchDateTime()
                    .toGregorianCalendar().getTime());
            match.setTeam1Name(matchdata.getNameTeam1());
            match.setTeam2Name(matchdata.getNameTeam2());
        }

        // results
        int oldResultTeam1 = match.getTeam1Result();
        int oldResultTeam2 = match.getTeam2Result();
        ArrayOfMatchResult results = matchdata.getMatchResults();
        for (MatchResult result : results.getMatchResult()) {
            //only use the endresult
            if (result.getResultOrderID() == 1) {
                match.setTeam1Result(result.getPointsTeam1());
                match.setTeam2Result(result.getPointsTeam2());
            }
        }

        if (oldResultTeam1 != match.getTeam1Result() || oldResultTeam2 != match.getTeam2Result()) {
            ps.saveMatch(match);
            return true;
        }

        return false;
    }

}
